/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// sound.h - framework used by dynamic-link libraries
//


#ifndef __FRAMEWORK_SOUND_H__
#define __FRAMEWORK_SOUND_H__


/*
 ==============================================================================

 Sound System:

 The sound system is responsible for managing all the audio I/O, including
 sound effects, background music, and voice over network.

 ==============================================================================
*/

// Sound channels must be defined by the game code.
// This is the only channel used internally by the sound system.
#define SOUND_CHANNEL_ANY			0

// Sound parms
#define MAX_SOUND_PARMS				8

#define SOUNDPARM_VOLUME			0			// Volume scale
#define SOUNDPARM_PITCH				1			// Pitch scale
#define SOUNDPARM_DRYFILTER			2			// Low-pass filter gain scale (direct path)
#define SOUNDPARM_DRYFILTERHF		3			// Low-pass filter gain HF scale (direct path)
#define SOUNDPARM_WETFILTER			4			// Low-pass filter gain scale (reverb path)
#define SOUNDPARM_WETFILTERHF		5			// Low-pass filter gain HF scale (reverb path)
#define SOUNDPARM_MINDISTANCE		6			// Used to override sound shader settings
#define SOUNDPARM_MAXDISTANCE		7			// Used to override sound shader settings

enum alHardwareType_t {
	ALHW_GENERIC,
	ALHW_CREATIVE
};

typedef struct soundShader_t		soundShader_t;

struct soundEmitter_t {
	int						emitterId;

	// Transformation matrix
	glqVec3					origin;
	glqVec3					direction;			// For directional cones (should be normalized)

	// Environment information
	bool					underwater;

	// Emitter attributes
	glqVec3					velocity;			// For doppler shifts

	// Sound parms
	float					soundParms[MAX_SOUND_PARMS];
};

struct soundListener_t {
	int						listenerId;

	// Transformation matrix
	glqVec3					origin;
	glqMat3					axis;

	// Environment information
	bool					underwater;

	// Listener attributes
	glqVec3					velocity;

	// Time in milliseconds for time dependent effects
	int						time;
};

struct alConfig_t {
	bool					initialized;

	alHardwareType_t		hardwareType;

	const char *			vendorString;
	const char *			rendererString;
	const char *			versionString;
	const char *			extensionsString;
	const char *			alcExtensionsString;

	bool					efxAvailable;
	bool					eaxRAMAvailable;

	int						maxAuxiliarySends;

	const char *			deviceName;
	const char *			deviceList;

	const char *			captureDeviceName;
	const char *			captureDeviceList;

	int						mixerFrequency;
	int						mixerRefresh;
	bool					mixerSync;

	int						monoSources;
	int						stereoSources;
};

// Functions exported by the engine
struct glqSound_t {
	// Loads and registers the given sound shader
	soundShader_t *			(*RegisterSoundShader)(const char *name);

	// Emitters are used to play sounds in the world.
	// When an emitter is removed all sounds can continue playing until
	// completed, or they can be stopped immediately.
	int						(*AddSoundEmitter)(const soundEmitter_t *soundEmitter);
	void					(*UpdateSoundEmitter)(int emitterHandle, const soundEmitter_t *soundEmitter);
	void					(*RemoveSoundEmitter)(int emitterHandle, bool stopAllSounds);

	// Plays a sound from the given emitter on the given channel.
	// SOUND_CHANNEL_ANY will never override playing sounds.
	void					(*PlaySoundFromEmitter)(int emitterHandle, int channelId, int startTime, soundShader_t *soundShader);

	// Stops all sounds playing from the given emitter on the given channel.
	// SOUND_CHANNEL_ANY will stop all sounds.
	void					(*StopSoundFromEmitter)(int emitterHandle, int channelId);

	// Returns the amplitude of all sounds playing from the given emitter on
	// the given channel.
	// SOUND_CHANNEL_ANY will account for all sounds.
	float					(*AmplitudeFromEmitter)(int emitterHandle, int channelId);

	// Returns true if there are any sounds playing from the given emitter on
	// the given channel.
	// SOUND_CHANNEL_ANY will check all sounds.
	bool					(*PlayingFromEmitter)(int emitterHandle, int channelId);

	// Clears all the active sound emitters, stopping all sounds immediately
	void					(*ClearAllSoundEmitters)();

	// Updates listener parameters
	void					(*PlaceListener)(const soundListener_t *soundListener);

	// Returns a shake amplitude for the current listener parameters
	float					(*ShakeAmplitudeForListener)();

	// Local sounds always play at full volume with no spatialization
	void					(*PlayLocalSound)(soundShader_t *soundShader);

	// Plays background music.
	// If already playing, the given tracks are added to a queue and played
	// after the current tracks have completely faded down.
	void					(*PlayMusic)(const char *introTrack, const char *loopTrack, int fadeUpTime);

	// Fades down and stops playing background music.
	// If there are any queued tracks, they will start playing immediately
	// after the current tracks have completely faded down.
	void					(*FadeMusic)(int fadeDownTime);

	// Stops playing background music immediately
	void					(*StopMusic)();

	// Returns information about the OpenAL subsystem
	alConfig_t				(*GetALConfig)();
};


#endif	// __FRAMEWORK_SOUND_H__